from sqlalchemy import select, update, delete
from sqlalchemy.ext.asyncio import AsyncSession

from module_kylin.entity.do.future_strategy_param_do import KylinFutureStrategyParam
from module_kylin.entity.vo.future_strategy_param_vo import (
    FutureStrategyParamModel,
    FutureStrategyParamPageQueryModel,
)
from utils.page_util import PageUtil


class FutureStrategyParamDao:
    """
    期货策略参数数据库操作层
    """

    @classmethod
    async def get_strategy_param_by_id(cls, db: AsyncSession, param_id: int):
        """
        根据ID获取策略参数信息

        :param db: orm对象
        :param param_id: 参数id
        :return: 策略参数信息对象
        """
        param_info = (
            await db.execute(select(KylinFutureStrategyParam).where(KylinFutureStrategyParam.id == param_id))
        ).scalars().first()

        return param_info

    @classmethod
    async def get_strategy_param_by_info(cls, db: AsyncSession, param: FutureStrategyParamModel):
        """
        根据策略实例名称和参数名获取参数信息

        :param db: orm对象
        :param param: 策略参数对象
        :return: 策略参数信息对象
        """
        query = select(KylinFutureStrategyParam)
        
        if param.strategy_instance:
            # 使用ilike进行不区分大小写的模糊匹配
            query = query.where(KylinFutureStrategyParam.strategy_instance.ilike(f'%{param.strategy_instance}%'))
        if param.param_name:
            # 使用ilike进行不区分大小写的模糊匹配
            query = query.where(KylinFutureStrategyParam.param_name.ilike(f'%{param.param_name}%'))
        
        param_info = (await db.execute(query)).scalars().first()
        return param_info

    @classmethod
    async def get_strategy_param_list(cls, db: AsyncSession, query_model: FutureStrategyParamPageQueryModel, is_page: bool = False):
        """
        获取策略参数列表

        :param db: orm对象
        :param query_model: 查询参数对象
        :param is_page: 是否开启分页
        :return: 策略参数列表
        """
        query = select(KylinFutureStrategyParam)
        
        if query_model.strategy_instance:
            # 使用ilike进行不区分大小写的模糊匹配
            query = query.where(KylinFutureStrategyParam.strategy_instance.ilike(f'%{query_model.strategy_instance}%'))
        if query_model.param_name:
            # 使用ilike进行不区分大小写的模糊匹配
            query = query.where(KylinFutureStrategyParam.param_name.ilike(f'%{query_model.param_name}%'))
        if query_model.param_value:
            # 使用ilike进行不区分大小写的模糊匹配
            query = query.where(KylinFutureStrategyParam.param_value.ilike(f'%{query_model.param_value}%'))
        
        # 按创建时间降序排序
        query = query.order_by(KylinFutureStrategyParam.create_time.desc())
        
        # 构建分页查询
        strategy_param_page = await PageUtil.paginate(db, query, query_model.page_num, query_model.page_size, is_page)
        
        return strategy_param_page

    @classmethod
    async def add_strategy_param(cls, db: AsyncSession, param: FutureStrategyParamModel):
        """
        添加策略参数

        :param db: orm对象
        :param param: 策略参数对象
        :return: 操作结果
        """
        db_param = KylinFutureStrategyParam(
            strategy_instance=param.strategy_instance,
            param_name=param.param_name,
            param_value=param.param_value
        )
        db.add(db_param)
        await db.flush()
        return db_param

    @classmethod
    async def update_strategy_param(cls, db: AsyncSession, param_id: int, param: FutureStrategyParamModel):
        """
        更新策略参数

        :param db: orm对象
        :param param_id: 参数id
        :param param: 策略参数对象
        :return: 操作结果
        """
        update_data = {}
        if param.strategy_instance is not None:
            update_data[KylinFutureStrategyParam.strategy_instance] = param.strategy_instance
        if param.param_name is not None:
            update_data[KylinFutureStrategyParam.param_name] = param.param_name
        if param.param_value is not None:
            update_data[KylinFutureStrategyParam.param_value] = param.param_value
        
        await db.execute(
            update(KylinFutureStrategyParam)
            .where(KylinFutureStrategyParam.id == param_id)
            .values(update_data)
        )

    @classmethod
    async def delete_strategy_param(cls, db: AsyncSession, param_id: int):
        """
        删除策略参数

        :param db: orm对象
        :param param_id: 参数id
        :return: 操作结果
        """
        await db.execute(
            delete(KylinFutureStrategyParam)
            .where(KylinFutureStrategyParam.id == param_id)
        )

    @classmethod
    async def batch_delete_strategy_param(cls, db: AsyncSession, param_ids: list[int]):
        """
        批量删除策略参数

        :param db: orm对象
        :param param_ids: 参数id列表
        :return: 操作结果
        """
        await db.execute(
            delete(KylinFutureStrategyParam)
            .where(KylinFutureStrategyParam.id.in_(param_ids))
        )
        
    @classmethod
    async def truncate_strategy_param(cls, db: AsyncSession):
        """
        清空策略参数表
        
        :param db: orm对象
        :return: 操作结果
        """
        await db.execute(
            delete(KylinFutureStrategyParam)
        )